package judesart.app.service;

import javax.inject.Inject;

import judesart.app.repository.ImageDAO;
import judesart.app.util.BlobMigrationRecord;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;

@Service("ImageService")
public class ImageServiceImpl implements ImageService {
    private final static Log LOGGER = LogFactory.getLog(ImageServiceImpl.class);
    @Inject
    private ImageDAO imageDAO;

    @Override
    public Image getImageConstrained(Long imageId, Integer maxWidth,
            Integer maxHeight, boolean isCrop) {
        judesart.app.domain.Image oldImage = imageDAO.findImageById(imageId);

        com.google.appengine.api.images.Image engImage;
        if (oldImage.getBlobKey() != null) {
        	String newBlobKey = BlobMigrationRecord.getNewBlobKey(oldImage.getBlobKey());
        	LOGGER.debug("Old Key [" + oldImage.getBlobKey() + "] new key [" 
        			 + newBlobKey + "]");
        	if (!newBlobKey.equals(oldImage.getBlobKey())){
        		oldImage.setBlobKey(newBlobKey);
        		imageDAO.updateImage(oldImage);
        	}
            engImage = ImagesServiceFactory.makeImageFromBlob(new BlobKey(oldImage.getBlobKey()));
        } else {
            engImage = ImagesServiceFactory.makeImage(oldImage.getData());
        }
        ImagesService service = ImagesServiceFactory.getImagesService();
        if (maxWidth == null)
            maxWidth = 1600;
        if (maxHeight == null)
            maxHeight = 1600;

        if (maxWidth != null && maxHeight != null) {
            if (isCrop) {
                Transform resize = ImagesServiceFactory.makeResize(100, 100);
                Image dummyImage = service.applyTransform(resize, engImage);
                int height = dummyImage.getHeight();
                int width = dummyImage.getWidth();
                LOGGER.debug(" > size dummy " + height + "," + width);
                double ratio = width / (height * 1.0);
                LOGGER.debug(" > ratio " + ratio);
                if (maxWidth < maxHeight * ratio) {
                    LOGGER.debug(" > maxHeight * ratio 1 " + maxHeight * ratio);
                    int newWidth = (int) (maxHeight * ratio);
                    if (newWidth < maxWidth)
                        newWidth = maxWidth;
                    resize = ImagesServiceFactory.makeResize(newWidth + 1,
                            maxHeight + 1);
                } else {
                    LOGGER.debug(" > maxHeight * ratio 2 " + maxHeight * ratio);
                    int newHeight = (int) (maxWidth / ratio);
                    if (newHeight < maxHeight)
                        newHeight = maxHeight;
                    resize = ImagesServiceFactory.makeResize(maxWidth + 1,
                            newHeight + 1);
                }
                engImage = service.applyTransform(resize, engImage);
                height = engImage.getHeight();
                width = engImage.getWidth();
                LOGGER.debug(" > size " + height + "," + width);
                double leftX = (width - maxWidth) / (width * 1.0) / 2.0;
                double rightX = 1.0 - leftX;
                double topY = (height - maxHeight) / (height * 1.0) / 2.0;
                double bottomY = 1.0 - topY;
                LOGGER.debug(" > crop " + leftX + "," + rightX + "," + topY
                        + "," + bottomY);
                Transform crop = ImagesServiceFactory.makeCrop(leftX, topY,
                        rightX, bottomY);
                engImage = service.applyTransform(crop, engImage);
            } else {
                Transform resize = ImagesServiceFactory.makeResize(maxWidth,
                        maxHeight);
                engImage = service.applyTransform(resize, engImage);
            }
        }

        return engImage;
    }
}
